Showing posts with label Content Query Web Part. Show all posts
Showing posts with label Content Query Web Part. Show all posts

Thursday, May 29, 2014

Sharepoint 2010 - Strange blog URL issue with site using Variations(Multilingual site). - REALLY WEIRD ISSUE!

Scenario/Symptoms

  • We have a site with variations. English/Spanish
  • Structure
    • Main Site > en > English Blog(Add 1 or 2 sample blogs)
    • Main Site > es > Spanish Blog(Add 1 or 2 sample blogs)
  • On the "Main Site" we added a "Content Query Web Part". Apply the below given setting.
  • Click on the link of any English blog. IT WORKS FINE!!!
  • Now click on the Spanish blog link. IT SAYS "PAGE NOT FOUND"!!!
  • Another way to get this is.
    • Go to the URL of Spanish blog site.
    • You can find the blogs on the page.
    • Click on the blog link IT SAYS "PAGE NOT FOUND"!!!.
    • Or navigate to "Administrar entradas de blog"(AllPosts.aspx). This page will show all the blogs in the list. Click on the blog link IT SAYS "PAGE NOT FOUND"!!!


Cause

We added a column to the list "Post". Now this small thing was causing the whole havoc.


Solution

There are 3 ways to
  1. Either don't add any column to list "Post". => BAD ONE
  2. Copy SharePoint Designer > Lists > Estrada De Blog and paste it there with name "Post". Don't delete the folder. Just need to duplicate and rename the folder.
  3. Read the blog => Sharepoint 2010 - Solution to blog URL issue with site using Variations(Multilingual site) to see the feature stapler solution for this issue.


Hope this helps. If you have any questions or a better solution, I am all open for it. Thanks for reading the blog.

Thursday, September 20, 2012

Override Content Query Webpart to do on the run filteration.

Problem

In one of my recent project I had a challenge of filtering the data with localization.
The project contained 2 languages, English and Spanish. I was trying to find out the out of the box way to get this done, but no help was available.


Solution

  1. Create a new empty project in Visual Studio 2010.
  2. Add a webpart to the project. "Webpart" not "Visual Web Part".
  3. Replace the Webpart class inherited and make it "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart".
  4. Please have a look at the code below. It will have on the fly list settings and field settings applied to the webpart.
  5. Build your code and deploy it. It should work.



Source Code


#region System
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
#endregion

// Create the Toolbar
namespace ToolBar.ToolBar
{
    [ToolboxItemAttribute(false)]
    public class ToolBar : Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart
    {
        #region Properties

        /// <summary>
        /// Root Site Name
        /// </summary>
        private string SiteUrl { get { return SPContext.Current.Site.RootWeb.Url; } }

        /// <summary>
        /// List Name
        /// </summary>
        private string ListName { get { return "ToolBar"; } }

        /// <summary>
        /// List of Url
        /// </summary>
        private string ListUrl
        {
            get
            {
                return string.Format("{0}/Lists/{1}/AllItems.aspx", SiteUrl, ListName);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// On Page Load
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            //On Load
            base.OnLoad(e);

            //General Settings
            this.AllowConnect = true;
            this.ShowUntargetedItems = false;
            this.AllowEdit = true;
            
            //this.FrameType = "NONE"; // TODO
            this.ChromeType = PartChromeType.None;
            this.ExportMode = WebPartExportMode.All;
            this.GroupByDirection = SortDirection.Desc;
            this.SortByDirection = SortDirection.Desc;
            
            this.ConnectionID = System.Guid.Empty;
            this.ListId = System.Guid.Empty;

            this.ViewFlag = "0";
            this.GroupingText = "GP Web Parts";
            this.Title = " Tool Bar";
            this.ContentTypeName = "Item";
            this.ItemStyle = "ToolBar";
            this.ServerTemplate = "100";
            this.GroupStyle = "DefaultHeader";
            this.WebUrl = "~sitecollection";
            this.Description = "Displays a dynamic view of content from your site.";
            this.Xsl = "<xsl:stylesheet xmlns:x=\"http://www.w3.org/2001/XMLSchema\" version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:cmswrt=\"http://schemas.microsoft.com/WebPart/v3/Publishing/runtime\" exclude-result-prefixes=\"xsl cmswrt x\" > <xsl:import href=\"/Style Library/XSL Style Sheets/Header.xsl\" /> <xsl:import href=\"/Style Library/XSL Style Sheets/ItemStyle.xsl\" /> <xsl:import href=\"/Style Library/XSL Style Sheets/ContentQueryMain.xsl\" /> </xsl:stylesheet>";
            this.SampleData = "<dsQueryResponse><Rows><Row Title=\"Item 1\" LinkUrl=\"http://Item1\" Group=\"Group Header\" __begincolumn=\"True\" __begingroup=\"True\" /><Row Title=\"Item 2\" LinkUrl=\"http://Item2\" __begincolumn=\"False\" __begingroup=\"False\" /><Row Title=\"Item 3\" LinkUrl=\"http://Item3\" __begincolumn=\"False\" __begingroup=\"False\" /></Rows></dsQueryResponse>";
            this.ParameterBindings = string.Empty;

            //Root Web
            using (SPWeb _web = SPContext.Current.Site.RootWeb)
            {
                //Assign the list to the CQWP
                SPList _listYCLToolBar = _web.GetListFromUrl(ListUrl);

                //Data mapping
                this.DataMappings = string.Format("Description:|LinkUrl:{2},TargetUrl,URL;|Title:{4},Title,Text;|NumComments:|PublishedDate:|PostCategory:|ImageUrlAltText:{0},Title,Text;|Author:|Language:{3},Language,Lookup;|ImageUrl:{1},Icon,URL;|Body:|"
                    , _listYCLToolBar.Fields["Title"].Id.ToString()
                    , "{" + _listYCLToolBar.Fields["Icon"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["TargetUrl"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Language"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Title"].Id.ToString() + "}"
                    );

                this.ListGuid = _listYCLToolBar.ID.ToString();

                this.DataMappingViewFields = string.Format("{0},URL;{1},URL;{2},Text;{3},Lookup;"
                    , "{" + _listYCLToolBar.Fields["TargetUrl"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Icon"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Title"].Id.ToString() + "}"
                    , "{" + _listYCLToolBar.Fields["Language"].Id.ToString() + "}"
                    );
                
                //Filter One
                this.FilterField1 = "Language";//Custom Field to get the variation work.
                this.FilterOperator1 = FilterFieldQueryOperator.Eq;
                this.FilterValue1 = System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag;
                this.FilterType1 = "Lookup";
                this.Filter1ChainingOperator = FilterChainingOperator.Or;

                this.Filter2ChainingOperator = FilterChainingOperator.Or;

                //Sorting
                this.SortByFieldType = "DateTime";
                this.SortBy = "Created";
            }            
        }

        /// <summary>
        /// Create Child Controls
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
        }

        #endregion
    }
}



Please let me know if there is any issue with this code or you can also correct me if I am wrong.

Friday, January 13, 2012

SharePoint 2010 - Custom Toolpart properties for CQWP.

Goal

Adding custom fields in the tool pane of Content Query Web Part and using them. A few days ago I was working on a project with a similar requirement. I figured out that we can extend ToolPane and add custom controls to it.

How to achieve?

  1. Create a blank SharePoint project in Microsoft Visual Studio 2010 with name "CustomContentQueryWebPart".
  2. Add a "Web Part" to the project with name "ExtendedCQWP" and not to be mistaken with "Visual Web Part".

  3. Added a class "ExtendedCQWPToolPart" for the ToolPane in a folder name "CustomToolPart". Once the classes are added the structure of the project will look like the picture given below.

  4. Use the code for "ExtendedCQWPToolPart".
    #region System
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.UI.WebControls;
    
    #endregion
    
    namespace CustomContentQueryWebPart.CustomToolPart
    {
        /// <summary>
        /// The extended tool part of Extended Content Query Web Part.
        /// Will have a DropdownList, RadioButtonList and TextBox
        /// Will use the values added in the controls as applied.
        /// </summary>
        public class ExtendedCQWPToolPart : Microsoft.SharePoint.WebPartPages.ToolPart
        {
            #region Properties
    
            /// <summary>
            /// Literal
            /// </summary>
            protected Literal Ltrl { get; set; }
    
            /// <summary>
            /// Text Box
            /// </summary>
            protected TextBox Txt { get; set; }
    
            /// <summary>
            /// Dropdownlist
            /// </summary>
            protected DropDownList Ddl { get; set; }
    
            /// <summary>
            /// Radiobutton
            /// </summary>
            protected RadioButtonList Rbtnl { get; set; }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// Constructor
            /// Applies the settings
            /// </summary>
            public ExtendedCQWPToolPart(string _ddlValue, string _rbtnValue, string _txtValue)
            {
                //Bind the ddl
                Ddl = new DropDownList();
                Ddl.Items.Insert(0, new ListItem("--- Select ---", ""));
                Ddl.Items.Insert(1, new ListItem("DDL 1"));
                Ddl.Items.Insert(2, new ListItem("DDL 2"));
                Ddl.Items.Insert(3, new ListItem("DDL 3"));
               
                //Radio Button the ddl
                Rbtnl = new RadioButtonList();
                Rbtnl.Items.Insert(0, new ListItem("RBTN 1"));
                Rbtnl.Items.Insert(1, new ListItem("RBTN 2"));
                Rbtnl.Items.Insert(2, new ListItem("RBTN 3"));
                Rbtnl.SelectedIndex = 0;
                
                //Text box
                Txt = new TextBox();
    
                //Refill the settings
                if (!string.IsNullOrEmpty(_ddlValue))
                {
                    Ddl.SelectedValue = _ddlValue;
                }
                if (!string.IsNullOrEmpty(_rbtnValue))
                {
                    Rbtnl.SelectedValue = _rbtnValue;
                }
                if (!string.IsNullOrEmpty(_txtValue))
                {
                    Txt.Text = _txtValue;
                }            
            }
    
            /// <summary>
            /// Applies the child controls
            /// </summary>
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
    
                #region Add the controls to the section
    
                //Title to the web part
                this.Title = "Extended Settings";
    
                //Add the contorls so that they show up on the screen
                Ltrl = new Literal();
                Ltrl.Text = "<b>Dropdown Selection</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Ddl);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br /><b>Radiobutton Selection</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Rbtnl);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br /><b>Textbox</b><br /><br />";
                this.Controls.Add(Ltrl);
                this.Controls.Add(Txt);
    
                Ltrl = new Literal();
                Ltrl.Text = "<br /><br />";
                this.Controls.Add(Ltrl);
    
                #endregion
            }
    
            /// <summary>
            /// Fires on the OK/Save is clicked in the tool part pane
            /// </summary>
            public override void ApplyChanges()
            {
                base.ApplyChanges();
    
                //Applies the custom settings to the content query web part
                ExtendedCQWP.ExtendedCQWP _parentWebPart = (ExtendedCQWP.ExtendedCQWP)this.ParentToolPane.SelectedWebPart;
                if (_parentWebPart != null)
                {
                    //Applies the control settings
                    _parentWebPart.DdlValue = Ddl.SelectedValue;
                    _parentWebPart.RbtnlValue = Rbtnl.SelectedValue;
                    _parentWebPart.TxtValue = Txt.Text;
    
                    //Applies the settings
                    _parentWebPart.ApplyChanges();
                }
                
            }
    
            #endregion
            
        }
    }
    
  5. For "ExtendedCQWP" add a reference of Microsoft.Sharepoint.Publishing and the code is given below.

    #region System
    
    using System;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    using System.Collections.Generic;
    using Microsoft.SharePoint.WebPartPages;
    
    #endregion
    
    namespace CustomContentQueryWebPart.ExtendedCQWP
    {
        /// <summary>
        /// Sample extended Content Query Web Part
        /// </summary>
        [ToolboxItemAttribute(false)]
        public class ExtendedCQWP : Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart
        {
            #region Properties
    
            /// <summary>
            /// Txt Value
            /// </summary>
            public string TxtValue { get; set; }
    
            /// <summary>
            /// Radio button Value
            /// </summary>
            public string RbtnlValue { get; set; }
    
            /// <summary>
            /// Txt Value
            /// </summary>
            public string DdlValue { get; set; }
    
            #endregion
    
            #region Methods
    
            /// <summary>
            /// Create Child Controls
            /// </summary>
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
            }
    
            /// <summary>
            /// Override the get tool part
            /// </summary>
            /// <returns></returns>
            public override ToolPart[] GetToolParts()
            {
                List<ToolPart> _toolParts = new List<ToolPart>(base.GetToolParts());
                _toolParts.Insert(0, new CustomToolPart.ExtendedCQWPToolPart(DdlValue, RbtnlValue, TxtValue));
                return _toolParts.ToArray();
            }
    
            /// <summary>
            /// Applies the changes
            /// </summary>
            public void ApplyChanges()
            {
                this.Title = string.Format("DDL : {0}, Rbtn : {1}, Txt : {2}", DdlValue, RbtnlValue, TxtValue);
            }
    
            #endregion
        }
    }
    
  6. I renamed the title in element.xml so the web part show with title "Custom Content Query Web Part".
  7. Edit the newly added webpart.

    /li>
  8. The right side of the tool pane will show like the below given picture. Make the modification as you want.



  9. On applying or saving the settings my code will set the title concatenating all the 3 values.


This was the simplest way of showing how to add the custom parameters in the tool pane. We can do many more things with it not just setting the title. You can also go through one of my old blog Override Content Query Webpart to do on the run filteration to get an idea of what else can be done with extending the classes.
Hope the blog helped you, please comment if you have any queries. I will be very much happy to answer them.

Tuesday, November 1, 2011

SharePoint 2010 - Use custom ItemStyle settings in Content Query Web Part.

Friends, I know many might find it easy to use the Custom Item Style for a Content Query Web Part. But, still I will try and explain a small process in a simplified way. Let's see if this is helpful for the starters.

Goal

The main goal is to use a Custom List name "Sample" and use a Content Query Web Part to show it with custom design style.

Process

  1. Create a custom list with name "Sample". The should just have 3 fields.
    1. Title - This is the main text to be shown for the picture.
    2. Picture - This is the hyperlink column for the picture of the item.
    3. Skills - This is a simple multiple line comment for the item.
  2. Go to any page. Add a web part. Drop a Content Query Web Part(CQWP) on the page from "Content Rollup".
  3. Click "Open tool pane".
  4. Content Query Tool Part > Query > Source > Show items from the following list: > Select "SAMPLE"
  5. Content Query Tool Part > Query > Presentation > Please see the picture as a default setting. I am going to leave it as it is.
  6. Click "Save" and the view of the web part will be a default text one which is going to look like picture below.
  7. On Clicking the picture it goes to the display record screen.

But now moving back to our goal. We need to show the data in a custom design layout. So follow the below given steps.
  1. Open a SharePoint 2010 designer.
  2. All Files > Style Library > XSL Style Sheets > ItemStyle.xsl(Edit it in advance mode)
  3. Find this element, copy it and paste it at the bottom of the XSL.
    <xsl:template name="Default" match="*" mode="itemstyle">...</xsl:template>
  4. Change the name and match to Sample.
    <xsl:template name="Sample" match="Row[@Style='Sample']" mode="itemstyle">...</xsl:template>
  5. Also if you edit the web part you can now see the item in the ItemStyle list. Make changes to map the correct fields too.

  6. Make the changes to the xsl(As you want the view of the list) or can copy the whole block and paste it at the bottom of the ItemStyle.xsl.
    <xsl:template name="Sample" match="Row[@Style='Sample']" mode="itemstyle">
            <xsl:variable name="SafeLinkUrl">
                <xsl:call-template name="OuterTemplate.GetSafeLink">
                    <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="SafeImageUrl">
                <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
                    <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="DisplayTitle">
                <xsl:call-template name="OuterTemplate.GetTitle">
                    <xsl:with-param name="Title" select="@Title"/>
                    <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
                </xsl:call-template>
            </xsl:variable>
            <table cellpadding="0" cellspacing="5" border="0" style="border:1px Solid #efefef;width:400px;">
                <tr>
                    <td style="width:100px" align="center">
                        <a href="{$SafeLinkUrl}" title="{@LinkToolTip}">
                            <img class="image" src="{$SafeImageUrl}" title="{@ImageUrlAltText}" />
                        </a>
                    </td>
                    <td valign="top" align="left"><a href="{$SafeLinkUrl}" title="{@LinkToolTip}">
                      <xsl:if test="$ItemsHaveStreams = 'True'">
                        <xsl:attribute name="onclick">
                          <xsl:value-of select="@OnClickForWebRendering"/>
                        </xsl:attribute>
                      </xsl:if>
                      <xsl:if test="$ItemsHaveStreams != 'True' and @OpenInNewWindow = 'True'">
                        <xsl:attribute name="onclick">
                          <xsl:value-of disable-output-escaping="yes" select="$OnClickTargetAttribute"/>
                        </xsl:attribute>
                      </xsl:if>
                      <xsl:value-of select="$DisplayTitle"/>
                    </a><br /><xsl:value-of select="@Description" disable-output-escaping="yes" /></td>
                </tr>
            </table> 
        </xsl:template>
    
  7. Once you are done with that you can see the below given view on the screen.
  8. Thats it.


I have tried my best to keep this as simple as possible for freshers who are learning SharePoint.

Tuesday, September 27, 2011

Sharepoint 2010 Enabling "Target Audience" programmatically for Sharepoint List

In this blog i have tried and explained how enable the "Target Audience" using C# for a list. But first I will show you how to enable manually.


Why do we have to enable "Target Audience" field?

To filter the data using audience in Content Query Web Part we have to enable this feature.



Manually

  1. Go to Sharepoint Site
  2. Site Actions > View All Site Content
  3. Select the SharePoint List you want to enable target audience.
  4. List Settings > Audience targeting settings
  5. Select the check box and save.
  6. This will add a field name "Target Audience" in the list.
  7. You can now give Item level target audience.

Programmatically

  1. In the event receiver where you are creating a Sharepoint List.
  2. Just use the code given below.
    #region Enable Target Audience
    
    XmlElement _fldElement = new XmlDocument().CreateElement("Field");
    _fldElement.SetAttribute("ID", "{61cbb965-1e04-4273-b658-eedaa662f48d}");
    _fldElement.SetAttribute("Type", "TargetTo");
    _fldElement.SetAttribute("Name", "Target_x0020_Audiences");
    _fldElement.SetAttribute("StaticName", "Target_x0020_Audiences");
    _fldElement.SetAttribute("DisplayName", "Target Audiences");
    _fldElement.SetAttribute("Required", "FALSE");
    _list.Fields.AddFieldAsXml(_fldElement.OuterXml);
    
    _list.Update();
    
    #endregion
  3. That should be it. See to the list if that column is there!

Thank you and hoping the blog helped you.